<?php

// +----------------------------------------------------------------------
// | ThinkXinrun
// +----------------------------------------------------------------------
// | 版权所有 2020 唐山鑫软网络科技有限公司 [ http://www.tsxrwl.com ]
// +----------------------------------------------------------------------
// | 官方网站: https://www.tsxrwl.com
// +----------------------------------------------------------------------

namespace app\validate\service;

// use app\validate\service\EmailValidationStrategy;
// use app\validate\service\IntValidationStrategy;
// use app\validate\service\LengthBetweenValidationStrategy;
// use app\validate\service\MaxLengthValidationStrategy;
// use app\validate\service\PhoneValidationStrategy;
// use app\validate\service\RequiredValidationStrategy;
use think\admin\Service as AdminService;

/**
 * 地区服务验证服务
 * Class ValidatorService
 * @package app\validate\service
 */
class ApiCheckService extends AdminService
{
    private $param;
    private $jsonData;
    private $log = [];

    public function __construct($param, $jsonData)
    {
        $this->param = $param;
        $this->jsonData = $jsonData;
    }

    /*
     *  @desc      参数预处理
     *  @author    saruri <saruri@163.com>
     *  @date      2023/03/15 19:59:57
     */
    public function _preUnset()
    {
        foreach ($this->param as $key => $value) {
            if (is_array($value) && empty($value)) {
                unset($this->param[$key]);
            }
        }
        //halt($this->param);
        //return $array;
    }

    public function validate()
    {
        //去掉参数的空数组
        $this->_preUnset();

        $strategies = $this->getValidationStrategies();
        //exit("测试");
        $this->log['jsonData'] = $this->jsonData;

        //必填参数检测
        //循环param 检测是否是required==true 则查看jsonData中是否有该字段 没有则直接error
        foreach ($this->param as $key => $value) {
            if (isset($value['required']) && $value['required'] == true) {
                if (!isset($this->jsonData[$key])) {
                    $this->log['err'][$key]['required'] = 'required';
                } else {
                    $this->log['pass'][$key]['required'] = 'required';
                }
            }
        }
        unset($key,$value);
        //如果有错误 直接返回log
        if (isset($this->log['err'])) {
            return $this->log;
        }


        foreach ($this->jsonData as $k => $data) {

            //$this->log['jsonData'][] = $data;

            //echo '字段大循环---' . $k . '=======>' . $data . "<br>\r\n";

            if (isset($this->param[$k])) {
                $rules = $this->param[$k];
                //echo '------参数中循环---' . $k . '=======>' . '' . "<br>\r\n";
                isset($rules['type']) || $rules['type']='string';
                //先执行type
                if (isset($strategies[$rules['type']])) {
                    $strategy = $strategies[$rules['type']];
                    if($rules['type']=='string'){
                        //halt("字符串");
                        $result = $strategy->validate($data,['allowed_chars'=>'utf8']);
                    }else{
                        $result = $strategy->validate($data);
                    }
                   

                    if (!$result) {
                        $this->log['err'][$k]['type'] = $rules['type'];
                    } else {
                        $this->log['pass'][$k]['type'] = $rules['type'];
                    }

                } else {
                    $this->log['waring'][$k] = 'no defined validateClass 未定义检测该类型{' . $rules['type'] . '}的CLASS';
                }

                //去掉type
                unset($rules['type']);
                //遍历剩下的验证
                foreach ($rules as $key => $rule) {

                    if (isset($strategies[$key])) {
                        $strategy = $strategies[$key];
                        $result = $strategy->validate($data, $rule);
                        if (!$result) {
                            $this->log['err'][$k][$key] = $rule;
                        } else {
                            $this->log['pass'][$k][$key] = $rule;
                        }

                    } else {
                        $this->log['waring'][$key] = 'no defined validateClass 未定义检测该类型{' . $key . '}的CLASS';
                    }
                    # code...
                    //echo '------------------小循环---' . $data . '---->' . $key . '======>' . $rule . "<br>\r\n";
                }

            } else {
                $this->log['tips'][$k] = '参数 {' . $k . '} 不在检测定义内';
            }

        }
        //halt($this->log);
        $this->delUnRequireErr();
        return empty($this->log['err']) ? null : $this->log;
    }

    /*
     *  @desc       //非必填 且为空 则去掉该字段err信息
     *  @author    saruri <saruri@163.com>
     *  @date      2023/03/14 17:37:41
     */
    public function delUnRequireErr()
    {

        foreach ($this->param as $key => $value) {
            if ($value['required'] == false and !isset($this->jsonData[$key])) {
                $this->log['ignore'][$key] = $this->log['err'][$key] ?? [];
                unset($this->log['err'][$key]);
            }
        }

    }

    //返回接口实现类
    private function getValidationStrategies()
    {
        return [
            'int' => new IntValidationStrategy(),
            'required' => new RequiredValidationStrategy(),
            'maxLength' => new MaxLengthValidationStrategy(),
            'minLength' => new MinLengthValidationStrategy(),
            'numberBetween' => new NumberBetweenValidationStrategy(),
            'email' => new EmailValidationStrategy(),
            'phone' => new PhoneValidationStrategy(),
            'string' => new StringValidationStrategy(),
        ];
    }

    private function retJson($status, $message, $data = null)
    {
        $response = [
            'status' => $status,
            'message' => $message,
        ];

        if (!is_null($data)) {
            $response['data'] = $data;
        }

        return json_encode($response);
    }
}
